<template>
  <!-- 沟通记录 -->
  <view class="mt-12 bg-white rounded-md p-12">
    <view class="pb-8 font-bold text-base border-b border-solid border-gray-100">沟通记录</view>
    <DataLoading v-if="msgLoading" />
    <template v-else>
      <!-- 下拉刷新区域 -->
      <scroll-view
        :scroll-y="true"
        :enhanced="true"
        :show-scrollbar="false"
        :refresher-enabled="!pageParams.isLoadAll"
        :refresher-triggered="refreshing"
        @refresherrefresh="onRefresh"
      >
        <!-- 消息列表 -->
        <template v-if="messageList.length">
          <view v-if="refreshing" class="py-10 text-center text-gray-400 text-xs">加载中...</view>
          <view
            v-if="pageParams.isLoadAll && messageList.length >= pageParams.limit"
            class="py-10 text-center text-gray-400 text-xs"
          >
            ---没有更多了---
          </view>
          <view
            v-for="(message, index) in messageList"
            :key="index"
            class="flex gap-x-10 py-12"
            :class="{ 'flex-row-reverse': message.isOwn }"
          >
            <!-- 用户头像 -->
            <view class="flex">
              <image class="w-26 h-26 bg-gray-100 rounded-full" :src="message.sender?.avatar" mode="aspectFill" />
            </view>
            <!-- 消息内容 -->
            <view class="flex-1">
              <!-- 用户名和时间 -->
              <view class="flex text-xs text-gray-400" :class="{ 'flex-row-reverse': message.isOwn }">
                <text>{{ message.sender?.name }}</text>
                <text v-if="message.sender_role && message.sender_role != 'customer'" class="mx-2">
                  ({{ ROLE_MAP[message.sender_role] }})
                </text>
                <text class="mx-5">{{ message.created_at.substring(5, 16) }}</text>
              </view>
              <!-- 消息文本 -->
              <view class="flex mt-6" :class="{ 'flex-row-reverse': message.isOwn }">
                <text class="p-6 rounded-md leading-[1.5]" :class="message.isOwn ? 'bg-blue-100' : 'bg-gray-100'">
                  {{ message.message }}
                </text>
              </view>
              <!-- 附件 -->
              <view
                v-if="message.attachments?.length"
                class="flex flex-wrap gap-10 mt-6"
                :class="{ 'justify-end': message.isOwn }"
              >
                <view
                  v-for="item in message.attachments"
                  :key="item.id"
                  class="flex items-center px-4 bg-gray-50 rounded text-xs"
                  @click="previewFile(item)"
                >
                  <uni-icons
                    :type="item.type === 'image' ? 'image' : 'paperclip'"
                    size="18"
                    color="#409eff"
                  ></uni-icons>
                  <text class="max-w-[100px] line-clamp-1">
                    {{ item.file_name }}
                  </text>
                </view>
              </view>
            </view>
          </view>
        </template>
        <EmptyData v-else />
      </scroll-view>
      <!-- 消息回复框 -->
      <view class="bottom_fixed_wrapper bg-white">
        <view class="flex-1">
          <!-- 文本输入区域 -->
          <view class="flex justify-between items-end">
            <view class="input_box flex-1">
              <uni-easyinput
                v-model="inputValue"
                type="textarea"
                :rows="1"
                placeholder="请输入内容"
                autoHeight
                confirmType="send"
                @confirm="sendMessage"
              />
            </view>
            <!-- 功能按钮区域 -->
            <view class="flex justify-between items-center gap-x-6 ml-10">
              <!-- 表情按钮 -->
              <view class="flex" @click="toggleEmojiPanel">
                <image class="w-24 h-24" src="/static/images/icons/face.png" mode="aspectFill" />
              </view>
              <!-- 更多按钮（上传文件/图片） -->
              <view @click="toggleUploadPanel">
                <uni-icons type="plus" size="28"></uni-icons>
              </view>
              <!-- 发送按钮 -->
              <view
                class="px-10 py-4 rounded-md"
                @click="sendMessage"
                :class="{
                  'bg-blue-500 text-white': !!inputValue.trim(),
                  'bg-gray-200 text-gray-400': !inputValue.trim(),
                }"
              >
                发送
              </view>
            </view>
          </view>
          <!-- 表情选择面板 -->
          <view v-if="showEmojiPanel" class="mt-10 border border-gray-200 rounded bg-white max-h-[200px]">
            <scroll-view class="h-150" scroll-y="true">
              <view class="flex flex-wrap gap-12 p-12">
                <view class="text-2xl" v-for="(emoji, index) in emojiList" :key="index" @click="selectEmoji(emoji)">
                  {{ emoji }}
                </view>
              </view>
            </scroll-view>
          </view>
          <!-- 上传选项面板 -->
          <view v-if="showUploadPanel" class="flex items-center mt-12">
            <view class="w-50 text-center" @click="chooseFile('image')">
              <uni-icons type="image" size="28" color="#999"></uni-icons>
              <view class="mt-2 text-xs text-gray-600">图片</view>
            </view>
            <view class="w-50 text-center" @click="chooseFile('file')">
              <uni-icons type="paperclip" size="28" color="#999"></uni-icons>
              <view class="mt-2 text-xs text-gray-600">文件</view>
            </view>
          </view>
          <!-- 已选择的附件展示 -->
          <view v-if="uploadList.length > 0" class="mt-10">
            <view
              class="flex justify-between items-center p-4 bg-gray-100 rounded-md mb-4"
              v-for="(file, index) in uploadList"
              :key="index"
            >
              <view class="flex items-center gap-4">
                <uni-icons :type="file.type === 'image' ? 'image' : 'paperclip'" size="20" color="#409eff"></uni-icons>
                <view class="flex-1 text-xs line-clamp-1">
                  {{ file.fileName }}
                </view>
              </view>
              <view @click="removeAttachment(index)">
                <uni-icons type="close" size="20" color="#f56161"></uni-icons>
              </view>
            </view>
          </view>
        </view>
      </view>
    </template>
  </view>
</template>

<script setup>
import { ref, defineProps, onMounted } from 'vue';
import { hostUrl } from '@/libs/config.js';
import { USER_ACCESS_TOKEN } from '@/libs/config.js';
import { getWorkOrderMessageListApi, sendWorkOrderMessageApi } from '@/api/service';
import { usePage } from '@/utils/usePublic';
import { getFileTypeWithExt } from '@/utils/utils.js';
import { openDocument } from '@/utils/index';
import emojiList from '@/utils/emojiList.js';

const pageParams = usePage();
const props = defineProps({
  uploadKey: {
    type: String,
    default: 'message',
  },
  serviceId: {
    type: Number,
    default: 0,
  },
});
const ROLE_MAP = {
  customer: '客户',
  agent: '律师',
  chat: '客服',
};
// 数据模型
const refreshing = ref(false);
const noMoreData = ref(false);

onMounted(() => {
  initData();
});

const initData = () => {
  stopRefresh();
  noMoreData.value = false;
  pageParams.page = 1;
  getMessageList();
};
// 获取消息列表
const msgLoading = ref(true);
const messageList = ref([]);
const userInfo = uni.getStorageSync('userInfo');
const getMessageList = async () => {
  const { code, data } = await getWorkOrderMessageListApi(props.serviceId, { ...pageParams });
  msgLoading.value = false;
  stopRefresh();
  if (code === 200) {
    data.list.forEach(item => {
      item.isOwn = item.sender_id === userInfo.id;
      if (item.attachments?.length) {
        item.attachments.forEach(file => {
          const ext = file.file_name.substring(file.file_name.lastIndexOf('.') + 1);
          file.type = getFileTypeWithExt(ext);
        });
      }
    });
    messageList.value = data.list.reverse().concat(messageList.value);
    pageParams.isLoadAll = data.list.length < pageParams.limit;
  }
};
// 下拉刷新
const onRefresh = () => {
  refreshing.value = true;
  if (pageParams.isLoadAll) {
    setTimeout(() => {
      stopRefresh();
    }, 200);
    return;
  }
  pageParams.page++;
  getMessageList();
};

// 停止刷新
const stopRefresh = () => {
  refreshing.value = false;
};

// 消息回复
const inputValue = ref('');
const showEmojiPanel = ref(false);
const showUploadPanel = ref(false);

// 切换表情面板
const toggleEmojiPanel = () => {
  showEmojiPanel.value = !showEmojiPanel.value;
  showUploadPanel.value = false;
};

// 切换上传面板
const toggleUploadPanel = () => {
  showUploadPanel.value = !showUploadPanel.value;
  showEmojiPanel.value = false;
};

// 选择表情
const selectEmoji = emoji => {
  inputValue.value += emoji;
};

// 选择文件
const uploadFileType = ref('');
const uploadList = ref([]);
const chooseFile = type => {
  uploadFileType.value = type;
  uploadToServer().then(res => {
    uploadList.value.push(...res);
  });
};

// 选择文件上传到服务器
const uploadToServer = () => {
  return new Promise(resolve => {
    if (uploadFileType.value === 'file') {
      // #ifdef MP-WEIXIN
      wx.chooseMessageFile({
        count: 1,
        type: 'file',
        success(res) {
          wx.showLoading({
            title: '上传中',
          });
          chooseFileComplete(res.tempFiles, resolve);
        },
      });
      // #endif
      //  #ifndef MP-WEIXIN
      uni.chooseFile({
        type: 'all',
        extension: ['.doc', '.docx', '.pdf'],
        success(res) {
          wx.showLoading({
            title: '上传中',
          });
          chooseFileComplete(res.tempFiles, resolve);
        },
      });
      // #endif
    } else {
      uni.chooseImage({
        count: 1,
        sourceType: ['album', 'camera'],
        success: res => {
          uni.showLoading({
            title: '上传中',
          });
          chooseFileComplete(res.tempFiles, resolve);
        },
      });
    }
  });
};

function chooseFileComplete(tempFiles, resolve) {
  toBackEnd(tempFiles).then(list => {
    resolve(list);
  });
}

function toBackEnd(files) {
  const token = uni.getStorageSync(USER_ACCESS_TOKEN);
  return new Promise(resolve => {
    const result = [];
    let count = 0;
    for (let i = 0; i < files.length; i++) {
      uni.uploadFile({
        url: `${hostUrl}/channel/upload_file`,
        filePath: files[i].path,
        header: {
          Authorization: `Bearer ${token}`,
        },
        name: 'file',
        formData: {
          source: props.uploadKey,
        },
        success: res => {
          const rt = JSON.parse(res.data);
          if (rt.code === 200) {
            const { data } = rt;
            result.push({
              type: uploadFileType.value,
              fileName: data.file_name,
              fileUrl: data.file_url,
              fileId: data.id,
            });
          } else {
            uni.showToast({
              title: rt.message,
              icon: 'none',
            });
          }
        },
        complete: () => {
          count++;
          if (count === files.length) {
            uni.hideLoading();
            resolve(result);
          }
        },
      });
    }
  });
}
// 移除附件
const removeAttachment = index => {
  uploadList.value.splice(index, 1);
};
// 发送消息
const sendMessage = async () => {
  if (!inputValue.value.trim()) {
    uni.showToast({
      title: '请输入内容',
      icon: 'none',
    });
    return;
  }
  const ids = uploadList.value.map(item => item.fileId);
  const { code } = await sendWorkOrderMessageApi(props.serviceId, {
    message: inputValue.value.trim(),
    attachment_ids: ids,
  });
  if (code === 200) {
    // 清空输入框和附件
    inputValue.value = '';
    uploadList.value = [];
    showEmojiPanel.value = false;
    showUploadPanel.value = false;
    initData();
  }
};
// 预览文件
const previewFile = file => {
  if (file.type === 'image') {
    uni.previewImage({
      urls: [file.file_url],
    });
  } else {
    openDocument(file.file_url);
  }
};
</script>
